{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import scipy.spatial.distance as ssd\n",
    "from collections import defaultdict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "      <th>rating</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id  item_id  rating\n",
       "0        1        1       5\n",
       "1        1        2       3\n",
       "2        1        3       4\n",
       "3        1        4       3\n",
       "4        1        5       3"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 读取训练集，使用到的列为user_id，item_id，rating\n",
    "df_training_data = pd.read_csv(\n",
    "    './data/movielen_rating_training.base',\n",
    "    names=['user_id','item_id','rating'],\n",
    "    usecols=[0,1,2],\n",
    "    sep='\\t')\n",
    "df_training_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 不重复的user_id与item_id列表\n",
    "user_id_s = df_training_data['user_id'].unique()\n",
    "item_id_s = df_training_data['item_id'].unique()\n",
    "# 建立id与index的索引\n",
    "# 例如：user_id_map[【user_id】] = user_index\n",
    "user_index_map = {}\n",
    "item_index_map = {}\n",
    "#以0-len（user_id_s）为索引\n",
    "for user_index in range(len(user_id_s)):\n",
    "    user_id = user_id_s[user_index]\n",
    "    user_index_map[user_id] = user_index\n",
    "for item_index in range(len(item_id_s)):\n",
    "    item_id = item_id_s[item_index]\n",
    "    item_index_map[item_id] = item_index\n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5., 3., 4., ..., 0., 0., 0.],\n",
       "       [4., 0., 0., ..., 0., 0., 0.],\n",
       "       [0., 0., 0., ..., 0., 0., 0.],\n",
       "       ...,\n",
       "       [5., 0., 0., ..., 0., 0., 0.],\n",
       "       [0., 0., 0., ..., 0., 0., 0.],\n",
       "       [0., 5., 0., ..., 0., 0., 0.]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 用户与物品的打分矩阵(行用户，列产品)\n",
    "user_item_rating_array = np.zeros(shape=(len(user_id_s),len(item_id_s)))\n",
    "# 用户打分商品的索引集合为空时默认未0占位\n",
    "user_rating_map = defaultdict(set)\n",
    "\n",
    "for row_index in df_training_data.index:\n",
    "    # 每一行的数据.iloc通过索引获取数据\n",
    "    row_data = df_training_data.iloc[row_index]\n",
    "    # 打分用户的索引\n",
    "    user_index = user_index_map[row_data['user_id']]\n",
    "    # 打分电影的索引\n",
    "    item_index = item_index_map[row_data['item_id']]\n",
    "    # 添加用户打分商品索引集合\n",
    "    user_rating_map[user_index].add(item_index)\n",
    "    # 矩阵中行=user_index，列=item_index的元素赋值为打分\n",
    "    user_item_rating_array[user_index,item_index] = row_data['rating']\n",
    "user_item_rating_array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3.68,\n",
       " 3.8,\n",
       " 3.0,\n",
       " 4.36,\n",
       " 2.96,\n",
       " 3.58,\n",
       " 3.89,\n",
       " 3.6,\n",
       " 4.17,\n",
       " 4.21,\n",
       " 3.53,\n",
       " 4.28,\n",
       " 3.14,\n",
       " 4.22,\n",
       " 3.03,\n",
       " 4.35,\n",
       " 3.16,\n",
       " 3.94,\n",
       " 3.6,\n",
       " 3.31,\n",
       " 2.66,\n",
       " 3.3,\n",
       " 3.64,\n",
       " 4.39,\n",
       " 4.05,\n",
       " 2.91,\n",
       " 3.3,\n",
       " 3.64,\n",
       " 3.94,\n",
       " 3.8,\n",
       " 3.91,\n",
       " 3.55,\n",
       " 3.64,\n",
       " 3.8,\n",
       " 3.0,\n",
       " 4.0,\n",
       " 3.46,\n",
       " 3.9,\n",
       " 3.85,\n",
       " 2.73,\n",
       " 3.94,\n",
       " 3.62,\n",
       " 3.68,\n",
       " 3.64,\n",
       " 3.48,\n",
       " 4.18,\n",
       " 3.56,\n",
       " 3.73,\n",
       " 2.73,\n",
       " 3.54,\n",
       " 3.75,\n",
       " 4.34,\n",
       " 4.0,\n",
       " 3.33,\n",
       " 3.8,\n",
       " 3.65,\n",
       " 3.63,\n",
       " 3.88,\n",
       " 4.02,\n",
       " 4.13,\n",
       " 2.83,\n",
       " 3.32,\n",
       " 2.98,\n",
       " 3.6,\n",
       " 3.98,\n",
       " 3.52,\n",
       " 3.42,\n",
       " 3.17,\n",
       " 3.74,\n",
       " 3.4,\n",
       " 3.82,\n",
       " 3.77,\n",
       " 3.65,\n",
       " 3.76,\n",
       " 3.18,\n",
       " 3.4,\n",
       " 3.46,\n",
       " 3.36,\n",
       " 4.19,\n",
       " 3.93,\n",
       " 3.57,\n",
       " 3.13,\n",
       " 3.4,\n",
       " 3.74,\n",
       " 3.55,\n",
       " 3.64,\n",
       " 3.78,\n",
       " 4.09,\n",
       " 4.15,\n",
       " 4.25,\n",
       " 3.9,\n",
       " 3.23,\n",
       " 3.0,\n",
       " 3.66,\n",
       " 3.48,\n",
       " 4.25,\n",
       " 3.97,\n",
       " 3.88,\n",
       " 3.65,\n",
       " 3.03,\n",
       " 3.0,\n",
       " 2.56,\n",
       " 3.4,\n",
       " 2.79,\n",
       " 3.31,\n",
       " 3.71,\n",
       " 2.77,\n",
       " 3.41,\n",
       " 3.5,\n",
       " 3.09,\n",
       " 3.5,\n",
       " 3.92,\n",
       " 3.81,\n",
       " 3.63,\n",
       " 4.04,\n",
       " 3.06,\n",
       " 3.72,\n",
       " 4.64,\n",
       " 3.88,\n",
       " 3.57,\n",
       " 3.67,\n",
       " 3.97,\n",
       " 3.93,\n",
       " 3.5,\n",
       " 3.44,\n",
       " 3.7,\n",
       " 4.18,\n",
       " 3.58,\n",
       " 2.87,\n",
       " 4.08,\n",
       " 4.07,\n",
       " 3.71,\n",
       " 3.28,\n",
       " 3.58,\n",
       " 3.45,\n",
       " 4.55,\n",
       " 4.08,\n",
       " 4.3,\n",
       " 3.93,\n",
       " 3.6,\n",
       " 3.45,\n",
       " 3.8,\n",
       " 3.73,\n",
       " 3.67,\n",
       " 3.32,\n",
       " 3.68,\n",
       " 4.3,\n",
       " 4.0,\n",
       " 3.0,\n",
       " 3.8,\n",
       " 4.08,\n",
       " 4.29,\n",
       " 3.08,\n",
       " 3.96,\n",
       " 2.64,\n",
       " 3.78,\n",
       " 3.7,\n",
       " 3.84,\n",
       " 3.41,\n",
       " 4.09,\n",
       " 2.53,\n",
       " 3.35,\n",
       " 3.08,\n",
       " 4.06,\n",
       " 4.0,\n",
       " 3.3,\n",
       " 3.82,\n",
       " 3.26,\n",
       " 3.96,\n",
       " 3.67,\n",
       " 3.42,\n",
       " 3.0,\n",
       " 4.19,\n",
       " 3.8,\n",
       " 3.83,\n",
       " 3.64,\n",
       " 3.73,\n",
       " 3.72,\n",
       " 2.91,\n",
       " 3.85,\n",
       " 1.52,\n",
       " 4.14,\n",
       " 3.17,\n",
       " 3.71,\n",
       " 3.88,\n",
       " 3.33,\n",
       " 4.21,\n",
       " 3.9,\n",
       " 3.96,\n",
       " 3.39,\n",
       " 4.0,\n",
       " 3.45,\n",
       " 3.28,\n",
       " 2.94,\n",
       " 3.22,\n",
       " 3.24,\n",
       " 3.19,\n",
       " 3.25,\n",
       " 3.16,\n",
       " 4.0,\n",
       " 3.14,\n",
       " 2.85,\n",
       " 3.27,\n",
       " 3.63,\n",
       " 2.8,\n",
       " 1.88,\n",
       " 3.22,\n",
       " 3.73,\n",
       " 3.38,\n",
       " 3.99,\n",
       " 3.38,\n",
       " 4.24,\n",
       " 4.24,\n",
       " 3.87,\n",
       " 3.86,\n",
       " 3.93,\n",
       " 3.05,\n",
       " 3.61,\n",
       " 4.12,\n",
       " 3.8,\n",
       " 3.61,\n",
       " 3.03,\n",
       " 3.19,\n",
       " 3.09,\n",
       " 4.8,\n",
       " 3.65,\n",
       " 3.28,\n",
       " 2.86,\n",
       " 3.13,\n",
       " 3.92,\n",
       " 3.6,\n",
       " 3.89,\n",
       " 4.35,\n",
       " 3.1,\n",
       " 3.89,\n",
       " 3.36,\n",
       " 4.11,\n",
       " 3.21,\n",
       " 4.12,\n",
       " 3.6,\n",
       " 3.33,\n",
       " 4.27,\n",
       " 3.56,\n",
       " 3.71,\n",
       " 3.31,\n",
       " 2.95,\n",
       " 3.8,\n",
       " 3.19,\n",
       " 4.19,\n",
       " 3.83,\n",
       " 3.73,\n",
       " 4.55,\n",
       " 3.95,\n",
       " 3.15,\n",
       " 2.48,\n",
       " 4.07,\n",
       " 4.26,\n",
       " 3.62,\n",
       " 3.81,\n",
       " 4.17,\n",
       " 4.1,\n",
       " 3.21,\n",
       " 4.05,\n",
       " 4.19,\n",
       " 3.63,\n",
       " 3.19,\n",
       " 3.99,\n",
       " 2.93,\n",
       " 2.85,\n",
       " 4.29,\n",
       " 3.59,\n",
       " 4.39,\n",
       " 3.5,\n",
       " 4.03,\n",
       " 3.06,\n",
       " 3.42,\n",
       " 3.29,\n",
       " 4.17,\n",
       " 3.17,\n",
       " 3.65,\n",
       " 3.29,\n",
       " 3.4,\n",
       " 4.07,\n",
       " 3.61,\n",
       " 3.81,\n",
       " 3.84,\n",
       " 3.86,\n",
       " 3.72,\n",
       " 2.62,\n",
       " 3.42,\n",
       " 3.69,\n",
       " 4.14,\n",
       " 3.1,\n",
       " 3.5,\n",
       " 4.29,\n",
       " 4.26,\n",
       " 3.41,\n",
       " 4.19,\n",
       " 3.51,\n",
       " 3.75,\n",
       " 3.59,\n",
       " 2.5,\n",
       " 3.37,\n",
       " 3.46,\n",
       " 3.42,\n",
       " 3.33,\n",
       " 3.67,\n",
       " 3.83,\n",
       " 3.82,\n",
       " 3.0,\n",
       " 3.76,\n",
       " 4.48,\n",
       " 3.65,\n",
       " 3.67,\n",
       " 3.98,\n",
       " 3.11,\n",
       " 3.58,\n",
       " 3.69,\n",
       " 3.25,\n",
       " 3.73,\n",
       " 3.82,\n",
       " 4.22,\n",
       " 3.64,\n",
       " 4.39,\n",
       " 3.36,\n",
       " 3.22,\n",
       " 3.28,\n",
       " 3.41,\n",
       " 3.3,\n",
       " 4.45,\n",
       " 3.65,\n",
       " 4.14,\n",
       " 3.79,\n",
       " 3.53,\n",
       " 3.62,\n",
       " 3.01,\n",
       " 4.05,\n",
       " 4.12,\n",
       " 4.06,\n",
       " 4.11,\n",
       " 3.67,\n",
       " 3.48,\n",
       " 3.99,\n",
       " 3.7,\n",
       " 3.66,\n",
       " 3.33,\n",
       " 3.6,\n",
       " 3.77,\n",
       " 3.36,\n",
       " 4.4,\n",
       " 4.13,\n",
       " 3.79,\n",
       " 3.29,\n",
       " 3.72,\n",
       " 4.1,\n",
       " 3.47,\n",
       " 4.06,\n",
       " 3.71,\n",
       " 4.14,\n",
       " 3.97,\n",
       " 3.76,\n",
       " 3.28,\n",
       " 3.09,\n",
       " 3.36,\n",
       " 3.37,\n",
       " 4.35,\n",
       " 4.11,\n",
       " 3.31,\n",
       " 4.0,\n",
       " 3.68,\n",
       " 4.1,\n",
       " 4.23,\n",
       " 3.72,\n",
       " 3.32,\n",
       " 3.94,\n",
       " 3.64,\n",
       " 4.0,\n",
       " 3.41,\n",
       " 4.01,\n",
       " 3.16,\n",
       " 3.8,\n",
       " 3.55,\n",
       " 4.42,\n",
       " 4.19,\n",
       " 3.31,\n",
       " 3.83,\n",
       " 3.33,\n",
       " 4.12,\n",
       " 3.71,\n",
       " 3.75,\n",
       " 3.76,\n",
       " 4.07,\n",
       " 3.34,\n",
       " 3.81,\n",
       " 3.83,\n",
       " 3.31,\n",
       " 3.84,\n",
       " 3.62,\n",
       " 2.92,\n",
       " 3.65,\n",
       " 3.12,\n",
       " 3.83,\n",
       " 3.64,\n",
       " 3.25,\n",
       " 1.85,\n",
       " 3.47,\n",
       " 3.48,\n",
       " 3.78,\n",
       " 3.7,\n",
       " 3.09,\n",
       " 3.74,\n",
       " 3.95,\n",
       " 3.68,\n",
       " 3.95,\n",
       " 4.29,\n",
       " 3.85,\n",
       " 3.23,\n",
       " 2.87,\n",
       " 4.17,\n",
       " 4.22,\n",
       " 3.82,\n",
       " 3.41,\n",
       " 3.53,\n",
       " 3.3,\n",
       " 2.94,\n",
       " 3.82,\n",
       " 4.58,\n",
       " 3.94,\n",
       " 3.37,\n",
       " 3.51,\n",
       " 3.28,\n",
       " 3.67,\n",
       " 3.46,\n",
       " 3.73,\n",
       " 3.31,\n",
       " 3.75,\n",
       " 3.57,\n",
       " 4.07,\n",
       " 3.71,\n",
       " 4.15,\n",
       " 3.5,\n",
       " 3.15,\n",
       " 3.38,\n",
       " 3.71,\n",
       " 2.01,\n",
       " 2.74,\n",
       " 3.57,\n",
       " 3.37,\n",
       " 3.75,\n",
       " 3.86,\n",
       " 2.74,\n",
       " 3.44,\n",
       " 3.28,\n",
       " 2.97,\n",
       " 3.5,\n",
       " 3.47,\n",
       " 4.03,\n",
       " 3.68,\n",
       " 3.38,\n",
       " 3.42,\n",
       " 3.0,\n",
       " 3.97,\n",
       " 2.86,\n",
       " 4.04,\n",
       " 3.44,\n",
       " 3.47,\n",
       " 3.68,\n",
       " 3.99,\n",
       " 4.53,\n",
       " 3.58,\n",
       " 3.39,\n",
       " 4.23,\n",
       " 3.91,\n",
       " 4.08,\n",
       " 3.6,\n",
       " 3.37,\n",
       " 4.46,\n",
       " 3.42,\n",
       " 3.42,\n",
       " 3.73,\n",
       " 3.98,\n",
       " 3.42,\n",
       " 3.05,\n",
       " 3.99,\n",
       " 3.04,\n",
       " 3.22,\n",
       " 3.65,\n",
       " 3.36,\n",
       " 3.72,\n",
       " 2.79,\n",
       " 3.85,\n",
       " 3.53,\n",
       " 3.76,\n",
       " 3.87,\n",
       " 3.95,\n",
       " 3.03,\n",
       " 3.18,\n",
       " 3.29,\n",
       " 3.86,\n",
       " 3.34,\n",
       " 3.77,\n",
       " 3.11,\n",
       " 4.02,\n",
       " 3.62,\n",
       " 3.37,\n",
       " 3.67,\n",
       " 4.72,\n",
       " 3.83,\n",
       " 2.52,\n",
       " 2.77,\n",
       " 3.75,\n",
       " 4.33,\n",
       " 4.36,\n",
       " 3.84,\n",
       " 3.0,\n",
       " 4.1,\n",
       " 3.3,\n",
       " 3.64,\n",
       " 4.12,\n",
       " 3.43,\n",
       " 3.14,\n",
       " 4.33,\n",
       " 4.36,\n",
       " 3.49,\n",
       " 3.3,\n",
       " 3.24,\n",
       " 3.83,\n",
       " 3.72,\n",
       " 3.6,\n",
       " 3.89,\n",
       " 3.23,\n",
       " 4.12,\n",
       " 3.38,\n",
       " 4.08,\n",
       " 3.94,\n",
       " 3.87,\n",
       " 2.87,\n",
       " 3.62,\n",
       " 3.98,\n",
       " 3.71,\n",
       " 3.62,\n",
       " 3.49,\n",
       " 3.53,\n",
       " 2.81,\n",
       " 3.51,\n",
       " 3.9,\n",
       " 3.65,\n",
       " 3.67,\n",
       " 3.72,\n",
       " 3.68,\n",
       " 3.8,\n",
       " 3.1,\n",
       " 4.17,\n",
       " 3.57,\n",
       " 4.02,\n",
       " 4.2,\n",
       " 3.75,\n",
       " 4.2,\n",
       " 3.58,\n",
       " 3.4,\n",
       " 3.03,\n",
       " 3.54,\n",
       " 3.77,\n",
       " 3.41,\n",
       " 4.54,\n",
       " 3.44,\n",
       " 3.95,\n",
       " 3.37,\n",
       " 3.49,\n",
       " 2.68,\n",
       " 3.45,\n",
       " 3.25,\n",
       " 3.75,\n",
       " 3.52,\n",
       " 3.15,\n",
       " 3.53,\n",
       " 3.8,\n",
       " 2.67,\n",
       " 3.47,\n",
       " 3.55,\n",
       " 4.04,\n",
       " 3.27,\n",
       " 4.44,\n",
       " 3.54,\n",
       " 3.74,\n",
       " 3.33,\n",
       " 2.97,\n",
       " 3.74,\n",
       " 3.44,\n",
       " 3.5,\n",
       " 3.65,\n",
       " 3.81,\n",
       " 3.61,\n",
       " 3.48,\n",
       " 3.2,\n",
       " 3.6,\n",
       " 3.63,\n",
       " 3.68,\n",
       " 3.89,\n",
       " 3.58,\n",
       " 3.08,\n",
       " 3.79,\n",
       " 3.79,\n",
       " 3.3,\n",
       " 3.76,\n",
       " 3.97,\n",
       " 3.84,\n",
       " 3.67,\n",
       " 2.39,\n",
       " 3.73,\n",
       " 3.83,\n",
       " 3.37,\n",
       " 4.32,\n",
       " 3.13,\n",
       " 3.86,\n",
       " 3.63,\n",
       " 2.62,\n",
       " 3.29,\n",
       " 3.51,\n",
       " 3.83,\n",
       " 3.55,\n",
       " 3.39,\n",
       " 3.73,\n",
       " 3.53,\n",
       " 3.43,\n",
       " 2.34,\n",
       " 3.29,\n",
       " 4.7,\n",
       " 4.08,\n",
       " 3.32,\n",
       " 3.1,\n",
       " 3.66,\n",
       " 3.31,\n",
       " 3.37,\n",
       " 3.26,\n",
       " 4.45,\n",
       " 2.49,\n",
       " 3.54,\n",
       " 2.96,\n",
       " 4.23,\n",
       " 4.12,\n",
       " 3.62,\n",
       " 3.74,\n",
       " 4.0,\n",
       " 3.96,\n",
       " 2.95,\n",
       " 3.83,\n",
       " 3.26,\n",
       " 3.79,\n",
       " 3.15,\n",
       " 3.29,\n",
       " 3.14,\n",
       " 2.69,\n",
       " 3.69,\n",
       " 2.91,\n",
       " 2.54,\n",
       " 3.24,\n",
       " 3.73,\n",
       " 3.79,\n",
       " 2.58,\n",
       " 3.92,\n",
       " 3.87,\n",
       " 3.53,\n",
       " 3.75,\n",
       " 3.48,\n",
       " 3.67,\n",
       " 3.96,\n",
       " 3.52,\n",
       " 3.38,\n",
       " 3.85,\n",
       " 3.58,\n",
       " 3.24,\n",
       " 3.89,\n",
       " 3.66,\n",
       " 3.71,\n",
       " 3.58,\n",
       " 3.59,\n",
       " 3.43,\n",
       " 3.66,\n",
       " 4.0,\n",
       " 3.23,\n",
       " 3.14,\n",
       " 3.23,\n",
       " 3.49,\n",
       " 2.05,\n",
       " 4.56,\n",
       " 3.48,\n",
       " 4.83,\n",
       " 3.83,\n",
       " 3.15,\n",
       " 4.22,\n",
       " 3.28,\n",
       " 3.14,\n",
       " 4.15,\n",
       " 3.29,\n",
       " 3.93,\n",
       " 3.71,\n",
       " 2.84,\n",
       " 3.15,\n",
       " 3.67,\n",
       " 4.21,\n",
       " 2.45,\n",
       " 3.53,\n",
       " 3.78,\n",
       " 3.71,\n",
       " 3.31,\n",
       " 3.5,\n",
       " 3.2,\n",
       " 3.57,\n",
       " 3.7,\n",
       " 3.86,\n",
       " 3.77,\n",
       " 2.97,\n",
       " 3.52,\n",
       " 3.38,\n",
       " 3.89,\n",
       " 3.71,\n",
       " 3.69,\n",
       " 3.1,\n",
       " 3.97,\n",
       " 3.54,\n",
       " 3.62,\n",
       " 3.27,\n",
       " 2.16,\n",
       " 3.8,\n",
       " 3.0,\n",
       " 3.04,\n",
       " 3.58,\n",
       " 2.86,\n",
       " 3.24,\n",
       " 3.39,\n",
       " 3.7,\n",
       " 3.03,\n",
       " 3.61,\n",
       " 3.32,\n",
       " 3.0,\n",
       " 3.97,\n",
       " 3.68,\n",
       " 3.6,\n",
       " 3.4,\n",
       " 3.46,\n",
       " 3.46,\n",
       " 3.69,\n",
       " 3.85,\n",
       " 3.1,\n",
       " 3.64,\n",
       " 4.05,\n",
       " 3.72,\n",
       " 3.62,\n",
       " 3.09,\n",
       " 3.54,\n",
       " 3.21,\n",
       " 3.6,\n",
       " 3.38,\n",
       " 3.11,\n",
       " 3.19,\n",
       " 3.37,\n",
       " 3.88,\n",
       " 4.06,\n",
       " 3.24,\n",
       " 2.85,\n",
       " 3.05,\n",
       " 3.78,\n",
       " 3.69,\n",
       " 4.09,\n",
       " 3.35,\n",
       " 4.43,\n",
       " 3.27,\n",
       " 3.07,\n",
       " 4.3,\n",
       " 3.71,\n",
       " 4.0,\n",
       " 3.28,\n",
       " 2.06,\n",
       " 3.79,\n",
       " 3.47,\n",
       " 4.06,\n",
       " 2.95,\n",
       " 3.92,\n",
       " 3.87,\n",
       " 3.79,\n",
       " 2.79,\n",
       " 3.87,\n",
       " 3.85,\n",
       " 3.7,\n",
       " 3.87,\n",
       " 3.14,\n",
       " 3.34,\n",
       " 3.67,\n",
       " 3.02,\n",
       " 3.8,\n",
       " 3.13,\n",
       " 3.51,\n",
       " 4.31,\n",
       " 3.13,\n",
       " 3.6,\n",
       " 2.65,\n",
       " 3.33,\n",
       " 4.0,\n",
       " 3.75,\n",
       " 4.04,\n",
       " 3.49,\n",
       " 3.09,\n",
       " 3.67,\n",
       " 3.35,\n",
       " 3.64,\n",
       " 3.89,\n",
       " 4.13,\n",
       " 3.45,\n",
       " 4.42,\n",
       " 4.14,\n",
       " 3.5,\n",
       " 2.79,\n",
       " 2.97,\n",
       " 3.74,\n",
       " 3.84,\n",
       " 3.36,\n",
       " 3.48,\n",
       " 4.07,\n",
       " 3.0,\n",
       " 4.34,\n",
       " 3.12,\n",
       " 4.01,\n",
       " 2.6,\n",
       " 3.61,\n",
       " 3.83,\n",
       " 3.25,\n",
       " 3.12,\n",
       " 3.55,\n",
       " 3.75,\n",
       " 3.52,\n",
       " 2.96,\n",
       " 3.06,\n",
       " 3.93,\n",
       " 4.15,\n",
       " 3.86,\n",
       " 3.04,\n",
       " 4.12,\n",
       " 3.19,\n",
       " 4.14,\n",
       " 3.9,\n",
       " 3.74,\n",
       " 2.74,\n",
       " 3.51,\n",
       " 3.13,\n",
       " 3.74,\n",
       " 3.03,\n",
       " 4.29,\n",
       " 4.87,\n",
       " 4.53,\n",
       " 3.46,\n",
       " 3.47,\n",
       " 2.98,\n",
       " 3.21,\n",
       " 3.35,\n",
       " 3.42,\n",
       " 3.27,\n",
       " 3.43,\n",
       " 3.85,\n",
       " 3.24,\n",
       " 4.0,\n",
       " 4.36,\n",
       " 3.12,\n",
       " 3.82,\n",
       " 2.29,\n",
       " 2.7,\n",
       " 4.26,\n",
       " 2.95,\n",
       " 2.87,\n",
       " 3.45,\n",
       " 3.5,\n",
       " 3.38,\n",
       " 2.9,\n",
       " 3.82,\n",
       " 4.19,\n",
       " 4.19,\n",
       " 3.83,\n",
       " 3.27,\n",
       " 3.69,\n",
       " 3.43,\n",
       " 3.32,\n",
       " 4.05,\n",
       " 3.93,\n",
       " 3.72,\n",
       " 3.31,\n",
       " 3.36,\n",
       " 3.92,\n",
       " 4.3,\n",
       " 3.44,\n",
       " 3.86,\n",
       " 4.13,\n",
       " 4.0,\n",
       " 3.42,\n",
       " 3.64,\n",
       " 3.75,\n",
       " 2.98,\n",
       " 3.96,\n",
       " 3.5,\n",
       " 3.53,\n",
       " 2.56,\n",
       " 3.85,\n",
       " 3.45,\n",
       " 3.85,\n",
       " 3.74,\n",
       " 3.28,\n",
       " 3.8,\n",
       " 4.57,\n",
       " 3.55,\n",
       " 4.35,\n",
       " 3.17,\n",
       " 3.81,\n",
       " 3.81,\n",
       " 3.52,\n",
       " 3.09,\n",
       " 3.12,\n",
       " 3.37,\n",
       " 3.54,\n",
       " 3.35,\n",
       " 3.47,\n",
       " 3.23,\n",
       " 3.27,\n",
       " 3.37,\n",
       " 4.15,\n",
       " 3.76,\n",
       " 3.12,\n",
       " 3.3,\n",
       " 3.69,\n",
       " 4.69,\n",
       " 3.69,\n",
       " 2.97,\n",
       " 3.72,\n",
       " 3.97,\n",
       " 2.65,\n",
       " 3.7,\n",
       " 3.92,\n",
       " 3.75,\n",
       " 3.38,\n",
       " 3.27,\n",
       " 4.27,\n",
       " 3.46,\n",
       " 4.05,\n",
       " 4.27,\n",
       " 3.41]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算用户的平均打分向量\n",
    "def calculate_user_rating_mu():\n",
    "    user_rating_mu_s = []\n",
    "    for user_index in range(len(user_id_s)):\n",
    "        # 计算打过分的电影索引\n",
    "        item_rating_index_v = list(user_rating_map[user_index])\n",
    "        # 打过分的电影评分向量numy.take(m,n)获取m行的第n个数据\n",
    "        item_rating_v = np.take(\n",
    "            user_item_rating_array[user_index],\n",
    "            item_rating_index_v\n",
    "        )\n",
    "        # print(item_rating_v)\n",
    "        # 打分向量的平均值\n",
    "        mu = item_rating_v.mean()\n",
    "        # 保留两位小数\n",
    "        mu = round(mu,2)\n",
    "        user_rating_mu_s.append(mu)\n",
    "    return user_rating_mu_s\n",
    "# ----------------【也可以写成一句话】----------------------------\n",
    "# def calculate_user_rating_mu():\n",
    "#     return [\n",
    "#         round(\n",
    "#             np.take(\n",
    "#                 user_item_rating_array[user_index],\n",
    "#                 list(user_rating_map[user_index])\n",
    "#             ).mean(),\n",
    "#             2\n",
    "#         )\n",
    "#         for user_index in range(len(user_id_s))\n",
    "#     ]\n",
    "# -----------------------------------------------------------------\n",
    "# 得到用户打分的平均值，列表类型，列表索引对应user_index\n",
    "user_rating_mu_s = calculate_user_rating_mu()\n",
    "user_rating_mu_s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义用户相似度函数\n",
    "def calculate_sim(user_index1,user_index2):\n",
    "    # 取用户1和用户2公共打分的电影集合，转换成列表\n",
    "    intersection_index_s = list(\n",
    "        user_rating_map[user_index1] & user_rating_map[user_index2]\n",
    "    )\n",
    "    # 如果没有公共的打分项，相似度为0.0\n",
    "    if not intersection_index_s:\n",
    "        return 0.0\n",
    "    # 根据公共索引，取到用户1的打分向量，并去均值\n",
    "    v1 = np.take(\n",
    "        user_item_rating_array[user_index1],\n",
    "        intersection_index_s\n",
    "    ) - user_rating_mu_s[user_index1]\n",
    "    # 根据公共索引，取到用户2的打分向量，并去均值\n",
    "    v2 = np.take(\n",
    "        user_item_rating_array[user_index2],\n",
    "        intersection_index_s\n",
    "    ) - user_rating_mu_s[user_index2]\n",
    "    # 计算相似度\n",
    "    sim = 1 - ssd.cosine(v1,v2)\n",
    "    # 如果相似度不是数字（如果v1或v2是0向量），返回相似度0\n",
    "    if np.isnan(sim):\n",
    "        return 0.0\n",
    "    # 否则相似度保留两位小数，返回结果\n",
    "    else:\n",
    "        return round(sim,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "计算到用户：0与其余用户的相似度\n",
      "计算到用户：1与其余用户的相似度\n",
      "计算到用户：2与其余用户的相似度\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\武卓奇\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\scipy\\spatial\\distance.py:720: RuntimeWarning: invalid value encountered in double_scalars\n",
      "  dist = 1.0 - uv / np.sqrt(uu * vv)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "计算到用户：3与其余用户的相似度\n",
      "计算到用户：4与其余用户的相似度\n",
      "计算到用户：5与其余用户的相似度\n",
      "计算到用户：6与其余用户的相似度\n",
      "计算到用户：7与其余用户的相似度\n",
      "计算到用户：8与其余用户的相似度\n",
      "计算到用户：9与其余用户的相似度\n",
      "计算到用户：10与其余用户的相似度\n",
      "计算到用户：11与其余用户的相似度\n",
      "计算到用户：12与其余用户的相似度\n",
      "计算到用户：13与其余用户的相似度\n",
      "计算到用户：14与其余用户的相似度\n",
      "计算到用户：15与其余用户的相似度\n",
      "计算到用户：16与其余用户的相似度\n",
      "计算到用户：17与其余用户的相似度\n",
      "计算到用户：18与其余用户的相似度\n",
      "计算到用户：19与其余用户的相似度\n",
      "计算到用户：20与其余用户的相似度\n",
      "计算到用户：21与其余用户的相似度\n",
      "计算到用户：22与其余用户的相似度\n",
      "计算到用户：23与其余用户的相似度\n",
      "计算到用户：24与其余用户的相似度\n",
      "计算到用户：25与其余用户的相似度\n",
      "计算到用户：26与其余用户的相似度\n",
      "计算到用户：27与其余用户的相似度\n",
      "计算到用户：28与其余用户的相似度\n",
      "计算到用户：29与其余用户的相似度\n",
      "计算到用户：30与其余用户的相似度\n",
      "计算到用户：31与其余用户的相似度\n",
      "计算到用户：32与其余用户的相似度\n",
      "计算到用户：33与其余用户的相似度\n",
      "计算到用户：34与其余用户的相似度\n",
      "计算到用户：35与其余用户的相似度\n",
      "计算到用户：36与其余用户的相似度\n",
      "计算到用户：37与其余用户的相似度\n",
      "计算到用户：38与其余用户的相似度\n",
      "计算到用户：39与其余用户的相似度\n",
      "计算到用户：40与其余用户的相似度\n",
      "计算到用户：41与其余用户的相似度\n",
      "计算到用户：42与其余用户的相似度\n",
      "计算到用户：43与其余用户的相似度\n",
      "计算到用户：44与其余用户的相似度\n",
      "计算到用户：45与其余用户的相似度\n",
      "计算到用户：46与其余用户的相似度\n",
      "计算到用户：47与其余用户的相似度\n",
      "计算到用户：48与其余用户的相似度\n",
      "计算到用户：49与其余用户的相似度\n",
      "计算到用户：50与其余用户的相似度\n",
      "计算到用户：51与其余用户的相似度\n",
      "计算到用户：52与其余用户的相似度\n",
      "计算到用户：53与其余用户的相似度\n",
      "计算到用户：54与其余用户的相似度\n",
      "计算到用户：55与其余用户的相似度\n",
      "计算到用户：56与其余用户的相似度\n",
      "计算到用户：57与其余用户的相似度\n",
      "计算到用户：58与其余用户的相似度\n",
      "计算到用户：59与其余用户的相似度\n",
      "计算到用户：60与其余用户的相似度\n",
      "计算到用户：61与其余用户的相似度\n",
      "计算到用户：62与其余用户的相似度\n",
      "计算到用户：63与其余用户的相似度\n",
      "计算到用户：64与其余用户的相似度\n",
      "计算到用户：65与其余用户的相似度\n",
      "计算到用户：66与其余用户的相似度\n",
      "计算到用户：67与其余用户的相似度\n",
      "计算到用户：68与其余用户的相似度\n",
      "计算到用户：69与其余用户的相似度\n",
      "计算到用户：70与其余用户的相似度\n",
      "计算到用户：71与其余用户的相似度\n",
      "计算到用户：72与其余用户的相似度\n",
      "计算到用户：73与其余用户的相似度\n",
      "计算到用户：74与其余用户的相似度\n",
      "计算到用户：75与其余用户的相似度\n",
      "计算到用户：76与其余用户的相似度\n",
      "计算到用户：77与其余用户的相似度\n",
      "计算到用户：78与其余用户的相似度\n",
      "计算到用户：79与其余用户的相似度\n",
      "计算到用户：80与其余用户的相似度\n",
      "计算到用户：81与其余用户的相似度\n",
      "计算到用户：82与其余用户的相似度\n",
      "计算到用户：83与其余用户的相似度\n",
      "计算到用户：84与其余用户的相似度\n",
      "计算到用户：85与其余用户的相似度\n",
      "计算到用户：86与其余用户的相似度\n",
      "计算到用户：87与其余用户的相似度\n",
      "计算到用户：88与其余用户的相似度\n",
      "计算到用户：89与其余用户的相似度\n",
      "计算到用户：90与其余用户的相似度\n",
      "计算到用户：91与其余用户的相似度\n",
      "计算到用户：92与其余用户的相似度\n",
      "计算到用户：93与其余用户的相似度\n",
      "计算到用户：94与其余用户的相似度\n",
      "计算到用户：95与其余用户的相似度\n",
      "计算到用户：96与其余用户的相似度\n",
      "计算到用户：97与其余用户的相似度\n",
      "计算到用户：98与其余用户的相似度\n",
      "计算到用户：99与其余用户的相似度\n",
      "计算到用户：100与其余用户的相似度\n",
      "计算到用户：101与其余用户的相似度\n",
      "计算到用户：102与其余用户的相似度\n",
      "计算到用户：103与其余用户的相似度\n",
      "计算到用户：104与其余用户的相似度\n",
      "计算到用户：105与其余用户的相似度\n",
      "计算到用户：106与其余用户的相似度\n",
      "计算到用户：107与其余用户的相似度\n",
      "计算到用户：108与其余用户的相似度\n",
      "计算到用户：109与其余用户的相似度\n",
      "计算到用户：110与其余用户的相似度\n",
      "计算到用户：111与其余用户的相似度\n",
      "计算到用户：112与其余用户的相似度\n",
      "计算到用户：113与其余用户的相似度\n",
      "计算到用户：114与其余用户的相似度\n",
      "计算到用户：115与其余用户的相似度\n",
      "计算到用户：116与其余用户的相似度\n",
      "计算到用户：117与其余用户的相似度\n",
      "计算到用户：118与其余用户的相似度\n",
      "计算到用户：119与其余用户的相似度\n",
      "计算到用户：120与其余用户的相似度\n",
      "计算到用户：121与其余用户的相似度\n",
      "计算到用户：122与其余用户的相似度\n",
      "计算到用户：123与其余用户的相似度\n",
      "计算到用户：124与其余用户的相似度\n",
      "计算到用户：125与其余用户的相似度\n",
      "计算到用户：126与其余用户的相似度\n",
      "计算到用户：127与其余用户的相似度\n",
      "计算到用户：128与其余用户的相似度\n",
      "计算到用户：129与其余用户的相似度\n",
      "计算到用户：130与其余用户的相似度\n",
      "计算到用户：131与其余用户的相似度\n",
      "计算到用户：132与其余用户的相似度\n",
      "计算到用户：133与其余用户的相似度\n",
      "计算到用户：134与其余用户的相似度\n",
      "计算到用户：135与其余用户的相似度\n",
      "计算到用户：136与其余用户的相似度\n",
      "计算到用户：137与其余用户的相似度\n",
      "计算到用户：138与其余用户的相似度\n",
      "计算到用户：139与其余用户的相似度\n",
      "计算到用户：140与其余用户的相似度\n",
      "计算到用户：141与其余用户的相似度\n",
      "计算到用户：142与其余用户的相似度\n",
      "计算到用户：143与其余用户的相似度\n",
      "计算到用户：144与其余用户的相似度\n",
      "计算到用户：145与其余用户的相似度\n",
      "计算到用户：146与其余用户的相似度\n",
      "计算到用户：147与其余用户的相似度\n",
      "计算到用户：148与其余用户的相似度\n",
      "计算到用户：149与其余用户的相似度\n",
      "计算到用户：150与其余用户的相似度\n",
      "计算到用户：151与其余用户的相似度\n",
      "计算到用户：152与其余用户的相似度\n",
      "计算到用户：153与其余用户的相似度\n",
      "计算到用户：154与其余用户的相似度\n",
      "计算到用户：155与其余用户的相似度\n",
      "计算到用户：156与其余用户的相似度\n",
      "计算到用户：157与其余用户的相似度\n",
      "计算到用户：158与其余用户的相似度\n",
      "计算到用户：159与其余用户的相似度\n",
      "计算到用户：160与其余用户的相似度\n",
      "计算到用户：161与其余用户的相似度\n",
      "计算到用户：162与其余用户的相似度\n",
      "计算到用户：163与其余用户的相似度\n",
      "计算到用户：164与其余用户的相似度\n",
      "计算到用户：165与其余用户的相似度\n",
      "计算到用户：166与其余用户的相似度\n",
      "计算到用户：167与其余用户的相似度\n",
      "计算到用户：168与其余用户的相似度\n",
      "计算到用户：169与其余用户的相似度\n",
      "计算到用户：170与其余用户的相似度\n",
      "计算到用户：171与其余用户的相似度\n",
      "计算到用户：172与其余用户的相似度\n",
      "计算到用户：173与其余用户的相似度\n",
      "计算到用户：174与其余用户的相似度\n",
      "计算到用户：175与其余用户的相似度\n",
      "计算到用户：176与其余用户的相似度\n",
      "计算到用户：177与其余用户的相似度\n",
      "计算到用户：178与其余用户的相似度\n",
      "计算到用户：179与其余用户的相似度\n",
      "计算到用户：180与其余用户的相似度\n",
      "计算到用户：181与其余用户的相似度\n",
      "计算到用户：182与其余用户的相似度\n",
      "计算到用户：183与其余用户的相似度\n",
      "计算到用户：184与其余用户的相似度\n",
      "计算到用户：185与其余用户的相似度\n",
      "计算到用户：186与其余用户的相似度\n",
      "计算到用户：187与其余用户的相似度\n",
      "计算到用户：188与其余用户的相似度\n",
      "计算到用户：189与其余用户的相似度\n",
      "计算到用户：190与其余用户的相似度\n",
      "计算到用户：191与其余用户的相似度\n",
      "计算到用户：192与其余用户的相似度\n",
      "计算到用户：193与其余用户的相似度\n",
      "计算到用户：194与其余用户的相似度\n",
      "计算到用户：195与其余用户的相似度\n",
      "计算到用户：196与其余用户的相似度\n",
      "计算到用户：197与其余用户的相似度\n",
      "计算到用户：198与其余用户的相似度\n",
      "计算到用户：199与其余用户的相似度\n",
      "计算到用户：200与其余用户的相似度\n",
      "计算到用户：201与其余用户的相似度\n",
      "计算到用户：202与其余用户的相似度\n",
      "计算到用户：203与其余用户的相似度\n",
      "计算到用户：204与其余用户的相似度\n",
      "计算到用户：205与其余用户的相似度\n",
      "计算到用户：206与其余用户的相似度\n",
      "计算到用户：207与其余用户的相似度\n",
      "计算到用户：208与其余用户的相似度\n",
      "计算到用户：209与其余用户的相似度\n",
      "计算到用户：210与其余用户的相似度\n",
      "计算到用户：211与其余用户的相似度\n",
      "计算到用户：212与其余用户的相似度\n",
      "计算到用户：213与其余用户的相似度\n",
      "计算到用户：214与其余用户的相似度\n",
      "计算到用户：215与其余用户的相似度\n",
      "计算到用户：216与其余用户的相似度\n",
      "计算到用户：217与其余用户的相似度\n",
      "计算到用户：218与其余用户的相似度\n",
      "计算到用户：219与其余用户的相似度\n",
      "计算到用户：220与其余用户的相似度\n",
      "计算到用户：221与其余用户的相似度\n",
      "计算到用户：222与其余用户的相似度\n",
      "计算到用户：223与其余用户的相似度\n",
      "计算到用户：224与其余用户的相似度\n",
      "计算到用户：225与其余用户的相似度\n",
      "计算到用户：226与其余用户的相似度\n",
      "计算到用户：227与其余用户的相似度\n",
      "计算到用户：228与其余用户的相似度\n",
      "计算到用户：229与其余用户的相似度\n",
      "计算到用户：230与其余用户的相似度\n",
      "计算到用户：231与其余用户的相似度\n",
      "计算到用户：232与其余用户的相似度\n",
      "计算到用户：233与其余用户的相似度\n",
      "计算到用户：234与其余用户的相似度\n",
      "计算到用户：235与其余用户的相似度\n",
      "计算到用户：236与其余用户的相似度\n",
      "计算到用户：237与其余用户的相似度\n",
      "计算到用户：238与其余用户的相似度\n",
      "计算到用户：239与其余用户的相似度\n",
      "计算到用户：240与其余用户的相似度\n",
      "计算到用户：241与其余用户的相似度\n",
      "计算到用户：242与其余用户的相似度\n",
      "计算到用户：243与其余用户的相似度\n",
      "计算到用户：244与其余用户的相似度\n",
      "计算到用户：245与其余用户的相似度\n",
      "计算到用户：246与其余用户的相似度\n",
      "计算到用户：247与其余用户的相似度\n",
      "计算到用户：248与其余用户的相似度\n",
      "计算到用户：249与其余用户的相似度\n",
      "计算到用户：250与其余用户的相似度\n",
      "计算到用户：251与其余用户的相似度\n",
      "计算到用户：252与其余用户的相似度\n",
      "计算到用户：253与其余用户的相似度\n",
      "计算到用户：254与其余用户的相似度\n",
      "计算到用户：255与其余用户的相似度\n",
      "计算到用户：256与其余用户的相似度\n",
      "计算到用户：257与其余用户的相似度\n",
      "计算到用户：258与其余用户的相似度\n",
      "计算到用户：259与其余用户的相似度\n",
      "计算到用户：260与其余用户的相似度\n",
      "计算到用户：261与其余用户的相似度\n",
      "计算到用户：262与其余用户的相似度\n",
      "计算到用户：263与其余用户的相似度\n",
      "计算到用户：264与其余用户的相似度\n",
      "计算到用户：265与其余用户的相似度\n",
      "计算到用户：266与其余用户的相似度\n",
      "计算到用户：267与其余用户的相似度\n",
      "计算到用户：268与其余用户的相似度\n",
      "计算到用户：269与其余用户的相似度\n",
      "计算到用户：270与其余用户的相似度\n",
      "计算到用户：271与其余用户的相似度\n",
      "计算到用户：272与其余用户的相似度\n",
      "计算到用户：273与其余用户的相似度\n",
      "计算到用户：274与其余用户的相似度\n",
      "计算到用户：275与其余用户的相似度\n",
      "计算到用户：276与其余用户的相似度\n",
      "计算到用户：277与其余用户的相似度\n",
      "计算到用户：278与其余用户的相似度\n",
      "计算到用户：279与其余用户的相似度\n",
      "计算到用户：280与其余用户的相似度\n",
      "计算到用户：281与其余用户的相似度\n",
      "计算到用户：282与其余用户的相似度\n",
      "计算到用户：283与其余用户的相似度\n",
      "计算到用户：284与其余用户的相似度\n",
      "计算到用户：285与其余用户的相似度\n",
      "计算到用户：286与其余用户的相似度\n",
      "计算到用户：287与其余用户的相似度\n",
      "计算到用户：288与其余用户的相似度\n",
      "计算到用户：289与其余用户的相似度\n",
      "计算到用户：290与其余用户的相似度\n",
      "计算到用户：291与其余用户的相似度\n",
      "计算到用户：292与其余用户的相似度\n",
      "计算到用户：293与其余用户的相似度\n",
      "计算到用户：294与其余用户的相似度\n",
      "计算到用户：295与其余用户的相似度\n",
      "计算到用户：296与其余用户的相似度\n",
      "计算到用户：297与其余用户的相似度\n",
      "计算到用户：298与其余用户的相似度\n",
      "计算到用户：299与其余用户的相似度\n",
      "计算到用户：300与其余用户的相似度\n",
      "计算到用户：301与其余用户的相似度\n",
      "计算到用户：302与其余用户的相似度\n",
      "计算到用户：303与其余用户的相似度\n",
      "计算到用户：304与其余用户的相似度\n",
      "计算到用户：305与其余用户的相似度\n",
      "计算到用户：306与其余用户的相似度\n",
      "计算到用户：307与其余用户的相似度\n",
      "计算到用户：308与其余用户的相似度\n",
      "计算到用户：309与其余用户的相似度\n",
      "计算到用户：310与其余用户的相似度\n",
      "计算到用户：311与其余用户的相似度\n",
      "计算到用户：312与其余用户的相似度\n",
      "计算到用户：313与其余用户的相似度\n",
      "计算到用户：314与其余用户的相似度\n",
      "计算到用户：315与其余用户的相似度\n",
      "计算到用户：316与其余用户的相似度\n",
      "计算到用户：317与其余用户的相似度\n",
      "计算到用户：318与其余用户的相似度\n",
      "计算到用户：319与其余用户的相似度\n",
      "计算到用户：320与其余用户的相似度\n",
      "计算到用户：321与其余用户的相似度\n",
      "计算到用户：322与其余用户的相似度\n",
      "计算到用户：323与其余用户的相似度\n",
      "计算到用户：324与其余用户的相似度\n",
      "计算到用户：325与其余用户的相似度\n",
      "计算到用户：326与其余用户的相似度\n",
      "计算到用户：327与其余用户的相似度\n",
      "计算到用户：328与其余用户的相似度\n",
      "计算到用户：329与其余用户的相似度\n",
      "计算到用户：330与其余用户的相似度\n",
      "计算到用户：331与其余用户的相似度\n",
      "计算到用户：332与其余用户的相似度\n",
      "计算到用户：333与其余用户的相似度\n",
      "计算到用户：334与其余用户的相似度\n",
      "计算到用户：335与其余用户的相似度\n",
      "计算到用户：336与其余用户的相似度\n",
      "计算到用户：337与其余用户的相似度\n",
      "计算到用户：338与其余用户的相似度\n",
      "计算到用户：339与其余用户的相似度\n",
      "计算到用户：340与其余用户的相似度\n",
      "计算到用户：341与其余用户的相似度\n",
      "计算到用户：342与其余用户的相似度\n",
      "计算到用户：343与其余用户的相似度\n",
      "计算到用户：344与其余用户的相似度\n",
      "计算到用户：345与其余用户的相似度\n",
      "计算到用户：346与其余用户的相似度\n",
      "计算到用户：347与其余用户的相似度\n",
      "计算到用户：348与其余用户的相似度\n",
      "计算到用户：349与其余用户的相似度\n",
      "计算到用户：350与其余用户的相似度\n",
      "计算到用户：351与其余用户的相似度\n",
      "计算到用户：352与其余用户的相似度\n",
      "计算到用户：353与其余用户的相似度\n",
      "计算到用户：354与其余用户的相似度\n",
      "计算到用户：355与其余用户的相似度\n",
      "计算到用户：356与其余用户的相似度\n",
      "计算到用户：357与其余用户的相似度\n",
      "计算到用户：358与其余用户的相似度\n",
      "计算到用户：359与其余用户的相似度\n",
      "计算到用户：360与其余用户的相似度\n",
      "计算到用户：361与其余用户的相似度\n",
      "计算到用户：362与其余用户的相似度\n",
      "计算到用户：363与其余用户的相似度\n",
      "计算到用户：364与其余用户的相似度\n",
      "计算到用户：365与其余用户的相似度\n",
      "计算到用户：366与其余用户的相似度\n",
      "计算到用户：367与其余用户的相似度\n",
      "计算到用户：368与其余用户的相似度\n",
      "计算到用户：369与其余用户的相似度\n",
      "计算到用户：370与其余用户的相似度\n",
      "计算到用户：371与其余用户的相似度\n",
      "计算到用户：372与其余用户的相似度\n",
      "计算到用户：373与其余用户的相似度\n",
      "计算到用户：374与其余用户的相似度\n",
      "计算到用户：375与其余用户的相似度\n",
      "计算到用户：376与其余用户的相似度\n",
      "计算到用户：377与其余用户的相似度\n",
      "计算到用户：378与其余用户的相似度\n",
      "计算到用户：379与其余用户的相似度\n",
      "计算到用户：380与其余用户的相似度\n",
      "计算到用户：381与其余用户的相似度\n",
      "计算到用户：382与其余用户的相似度\n",
      "计算到用户：383与其余用户的相似度\n",
      "计算到用户：384与其余用户的相似度\n",
      "计算到用户：385与其余用户的相似度\n",
      "计算到用户：386与其余用户的相似度\n",
      "计算到用户：387与其余用户的相似度\n",
      "计算到用户：388与其余用户的相似度\n",
      "计算到用户：389与其余用户的相似度\n",
      "计算到用户：390与其余用户的相似度\n",
      "计算到用户：391与其余用户的相似度\n",
      "计算到用户：392与其余用户的相似度\n",
      "计算到用户：393与其余用户的相似度\n",
      "计算到用户：394与其余用户的相似度\n",
      "计算到用户：395与其余用户的相似度\n",
      "计算到用户：396与其余用户的相似度\n",
      "计算到用户：397与其余用户的相似度\n",
      "计算到用户：398与其余用户的相似度\n",
      "计算到用户：399与其余用户的相似度\n",
      "计算到用户：400与其余用户的相似度\n",
      "计算到用户：401与其余用户的相似度\n",
      "计算到用户：402与其余用户的相似度\n",
      "计算到用户：403与其余用户的相似度\n",
      "计算到用户：404与其余用户的相似度\n",
      "计算到用户：405与其余用户的相似度\n",
      "计算到用户：406与其余用户的相似度\n",
      "计算到用户：407与其余用户的相似度\n",
      "计算到用户：408与其余用户的相似度\n",
      "计算到用户：409与其余用户的相似度\n",
      "计算到用户：410与其余用户的相似度\n",
      "计算到用户：411与其余用户的相似度\n",
      "计算到用户：412与其余用户的相似度\n",
      "计算到用户：413与其余用户的相似度\n",
      "计算到用户：414与其余用户的相似度\n",
      "计算到用户：415与其余用户的相似度\n",
      "计算到用户：416与其余用户的相似度\n",
      "计算到用户：417与其余用户的相似度\n",
      "计算到用户：418与其余用户的相似度\n",
      "计算到用户：419与其余用户的相似度\n",
      "计算到用户：420与其余用户的相似度\n",
      "计算到用户：421与其余用户的相似度\n",
      "计算到用户：422与其余用户的相似度\n",
      "计算到用户：423与其余用户的相似度\n",
      "计算到用户：424与其余用户的相似度\n",
      "计算到用户：425与其余用户的相似度\n",
      "计算到用户：426与其余用户的相似度\n",
      "计算到用户：427与其余用户的相似度\n",
      "计算到用户：428与其余用户的相似度\n",
      "计算到用户：429与其余用户的相似度\n",
      "计算到用户：430与其余用户的相似度\n",
      "计算到用户：431与其余用户的相似度\n",
      "计算到用户：432与其余用户的相似度\n",
      "计算到用户：433与其余用户的相似度\n",
      "计算到用户：434与其余用户的相似度\n",
      "计算到用户：435与其余用户的相似度\n",
      "计算到用户：436与其余用户的相似度\n",
      "计算到用户：437与其余用户的相似度\n",
      "计算到用户：438与其余用户的相似度\n",
      "计算到用户：439与其余用户的相似度\n",
      "计算到用户：440与其余用户的相似度\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "计算到用户：441与其余用户的相似度\n",
      "计算到用户：442与其余用户的相似度\n",
      "计算到用户：443与其余用户的相似度\n",
      "计算到用户：444与其余用户的相似度\n",
      "计算到用户：445与其余用户的相似度\n",
      "计算到用户：446与其余用户的相似度\n",
      "计算到用户：447与其余用户的相似度\n",
      "计算到用户：448与其余用户的相似度\n",
      "计算到用户：449与其余用户的相似度\n",
      "计算到用户：450与其余用户的相似度\n",
      "计算到用户：451与其余用户的相似度\n",
      "计算到用户：452与其余用户的相似度\n",
      "计算到用户：453与其余用户的相似度\n",
      "计算到用户：454与其余用户的相似度\n",
      "计算到用户：455与其余用户的相似度\n",
      "计算到用户：456与其余用户的相似度\n",
      "计算到用户：457与其余用户的相似度\n",
      "计算到用户：458与其余用户的相似度\n",
      "计算到用户：459与其余用户的相似度\n",
      "计算到用户：460与其余用户的相似度\n",
      "计算到用户：461与其余用户的相似度\n",
      "计算到用户：462与其余用户的相似度\n",
      "计算到用户：463与其余用户的相似度\n",
      "计算到用户：464与其余用户的相似度\n",
      "计算到用户：465与其余用户的相似度\n",
      "计算到用户：466与其余用户的相似度\n",
      "计算到用户：467与其余用户的相似度\n",
      "计算到用户：468与其余用户的相似度\n",
      "计算到用户：469与其余用户的相似度\n",
      "计算到用户：470与其余用户的相似度\n",
      "计算到用户：471与其余用户的相似度\n",
      "计算到用户：472与其余用户的相似度\n",
      "计算到用户：473与其余用户的相似度\n",
      "计算到用户：474与其余用户的相似度\n",
      "计算到用户：475与其余用户的相似度\n",
      "计算到用户：476与其余用户的相似度\n",
      "计算到用户：477与其余用户的相似度\n",
      "计算到用户：478与其余用户的相似度\n",
      "计算到用户：479与其余用户的相似度\n",
      "计算到用户：480与其余用户的相似度\n",
      "计算到用户：481与其余用户的相似度\n",
      "计算到用户：482与其余用户的相似度\n",
      "计算到用户：483与其余用户的相似度\n",
      "计算到用户：484与其余用户的相似度\n",
      "计算到用户：485与其余用户的相似度\n",
      "计算到用户：486与其余用户的相似度\n",
      "计算到用户：487与其余用户的相似度\n",
      "计算到用户：488与其余用户的相似度\n",
      "计算到用户：489与其余用户的相似度\n",
      "计算到用户：490与其余用户的相似度\n",
      "计算到用户：491与其余用户的相似度\n",
      "计算到用户：492与其余用户的相似度\n",
      "计算到用户：493与其余用户的相似度\n",
      "计算到用户：494与其余用户的相似度\n",
      "计算到用户：495与其余用户的相似度\n",
      "计算到用户：496与其余用户的相似度\n",
      "计算到用户：497与其余用户的相似度\n",
      "计算到用户：498与其余用户的相似度\n",
      "计算到用户：499与其余用户的相似度\n",
      "计算到用户：500与其余用户的相似度\n",
      "计算到用户：501与其余用户的相似度\n",
      "计算到用户：502与其余用户的相似度\n",
      "计算到用户：503与其余用户的相似度\n",
      "计算到用户：504与其余用户的相似度\n",
      "计算到用户：505与其余用户的相似度\n",
      "计算到用户：506与其余用户的相似度\n",
      "计算到用户：507与其余用户的相似度\n",
      "计算到用户：508与其余用户的相似度\n",
      "计算到用户：509与其余用户的相似度\n",
      "计算到用户：510与其余用户的相似度\n",
      "计算到用户：511与其余用户的相似度\n",
      "计算到用户：512与其余用户的相似度\n",
      "计算到用户：513与其余用户的相似度\n",
      "计算到用户：514与其余用户的相似度\n",
      "计算到用户：515与其余用户的相似度\n",
      "计算到用户：516与其余用户的相似度\n",
      "计算到用户：517与其余用户的相似度\n",
      "计算到用户：518与其余用户的相似度\n",
      "计算到用户：519与其余用户的相似度\n",
      "计算到用户：520与其余用户的相似度\n",
      "计算到用户：521与其余用户的相似度\n",
      "计算到用户：522与其余用户的相似度\n",
      "计算到用户：523与其余用户的相似度\n",
      "计算到用户：524与其余用户的相似度\n",
      "计算到用户：525与其余用户的相似度\n",
      "计算到用户：526与其余用户的相似度\n",
      "计算到用户：527与其余用户的相似度\n",
      "计算到用户：528与其余用户的相似度\n",
      "计算到用户：529与其余用户的相似度\n",
      "计算到用户：530与其余用户的相似度\n",
      "计算到用户：531与其余用户的相似度\n",
      "计算到用户：532与其余用户的相似度\n",
      "计算到用户：533与其余用户的相似度\n",
      "计算到用户：534与其余用户的相似度\n",
      "计算到用户：535与其余用户的相似度\n",
      "计算到用户：536与其余用户的相似度\n",
      "计算到用户：537与其余用户的相似度\n",
      "计算到用户：538与其余用户的相似度\n",
      "计算到用户：539与其余用户的相似度\n",
      "计算到用户：540与其余用户的相似度\n",
      "计算到用户：541与其余用户的相似度\n",
      "计算到用户：542与其余用户的相似度\n",
      "计算到用户：543与其余用户的相似度\n",
      "计算到用户：544与其余用户的相似度\n",
      "计算到用户：545与其余用户的相似度\n",
      "计算到用户：546与其余用户的相似度\n",
      "计算到用户：547与其余用户的相似度\n",
      "计算到用户：548与其余用户的相似度\n",
      "计算到用户：549与其余用户的相似度\n",
      "计算到用户：550与其余用户的相似度\n",
      "计算到用户：551与其余用户的相似度\n",
      "计算到用户：552与其余用户的相似度\n",
      "计算到用户：553与其余用户的相似度\n",
      "计算到用户：554与其余用户的相似度\n",
      "计算到用户：555与其余用户的相似度\n",
      "计算到用户：556与其余用户的相似度\n",
      "计算到用户：557与其余用户的相似度\n",
      "计算到用户：558与其余用户的相似度\n",
      "计算到用户：559与其余用户的相似度\n",
      "计算到用户：560与其余用户的相似度\n",
      "计算到用户：561与其余用户的相似度\n",
      "计算到用户：562与其余用户的相似度\n",
      "计算到用户：563与其余用户的相似度\n",
      "计算到用户：564与其余用户的相似度\n",
      "计算到用户：565与其余用户的相似度\n",
      "计算到用户：566与其余用户的相似度\n",
      "计算到用户：567与其余用户的相似度\n",
      "计算到用户：568与其余用户的相似度\n",
      "计算到用户：569与其余用户的相似度\n",
      "计算到用户：570与其余用户的相似度\n",
      "计算到用户：571与其余用户的相似度\n",
      "计算到用户：572与其余用户的相似度\n",
      "计算到用户：573与其余用户的相似度\n",
      "计算到用户：574与其余用户的相似度\n",
      "计算到用户：575与其余用户的相似度\n",
      "计算到用户：576与其余用户的相似度\n",
      "计算到用户：577与其余用户的相似度\n",
      "计算到用户：578与其余用户的相似度\n",
      "计算到用户：579与其余用户的相似度\n",
      "计算到用户：580与其余用户的相似度\n",
      "计算到用户：581与其余用户的相似度\n",
      "计算到用户：582与其余用户的相似度\n",
      "计算到用户：583与其余用户的相似度\n",
      "计算到用户：584与其余用户的相似度\n",
      "计算到用户：585与其余用户的相似度\n",
      "计算到用户：586与其余用户的相似度\n",
      "计算到用户：587与其余用户的相似度\n",
      "计算到用户：588与其余用户的相似度\n",
      "计算到用户：589与其余用户的相似度\n",
      "计算到用户：590与其余用户的相似度\n",
      "计算到用户：591与其余用户的相似度\n",
      "计算到用户：592与其余用户的相似度\n",
      "计算到用户：593与其余用户的相似度\n",
      "计算到用户：594与其余用户的相似度\n",
      "计算到用户：595与其余用户的相似度\n",
      "计算到用户：596与其余用户的相似度\n",
      "计算到用户：597与其余用户的相似度\n",
      "计算到用户：598与其余用户的相似度\n",
      "计算到用户：599与其余用户的相似度\n",
      "计算到用户：600与其余用户的相似度\n",
      "计算到用户：601与其余用户的相似度\n",
      "计算到用户：602与其余用户的相似度\n",
      "计算到用户：603与其余用户的相似度\n",
      "计算到用户：604与其余用户的相似度\n",
      "计算到用户：605与其余用户的相似度\n",
      "计算到用户：606与其余用户的相似度\n",
      "计算到用户：607与其余用户的相似度\n",
      "计算到用户：608与其余用户的相似度\n",
      "计算到用户：609与其余用户的相似度\n",
      "计算到用户：610与其余用户的相似度\n",
      "计算到用户：611与其余用户的相似度\n",
      "计算到用户：612与其余用户的相似度\n",
      "计算到用户：613与其余用户的相似度\n",
      "计算到用户：614与其余用户的相似度\n",
      "计算到用户：615与其余用户的相似度\n",
      "计算到用户：616与其余用户的相似度\n",
      "计算到用户：617与其余用户的相似度\n",
      "计算到用户：618与其余用户的相似度\n",
      "计算到用户：619与其余用户的相似度\n",
      "计算到用户：620与其余用户的相似度\n",
      "计算到用户：621与其余用户的相似度\n",
      "计算到用户：622与其余用户的相似度\n",
      "计算到用户：623与其余用户的相似度\n",
      "计算到用户：624与其余用户的相似度\n",
      "计算到用户：625与其余用户的相似度\n",
      "计算到用户：626与其余用户的相似度\n",
      "计算到用户：627与其余用户的相似度\n",
      "计算到用户：628与其余用户的相似度\n",
      "计算到用户：629与其余用户的相似度\n",
      "计算到用户：630与其余用户的相似度\n",
      "计算到用户：631与其余用户的相似度\n",
      "计算到用户：632与其余用户的相似度\n",
      "计算到用户：633与其余用户的相似度\n",
      "计算到用户：634与其余用户的相似度\n",
      "计算到用户：635与其余用户的相似度\n",
      "计算到用户：636与其余用户的相似度\n",
      "计算到用户：637与其余用户的相似度\n",
      "计算到用户：638与其余用户的相似度\n",
      "计算到用户：639与其余用户的相似度\n",
      "计算到用户：640与其余用户的相似度\n",
      "计算到用户：641与其余用户的相似度\n",
      "计算到用户：642与其余用户的相似度\n",
      "计算到用户：643与其余用户的相似度\n",
      "计算到用户：644与其余用户的相似度\n",
      "计算到用户：645与其余用户的相似度\n",
      "计算到用户：646与其余用户的相似度\n",
      "计算到用户：647与其余用户的相似度\n",
      "计算到用户：648与其余用户的相似度\n",
      "计算到用户：649与其余用户的相似度\n",
      "计算到用户：650与其余用户的相似度\n",
      "计算到用户：651与其余用户的相似度\n",
      "计算到用户：652与其余用户的相似度\n",
      "计算到用户：653与其余用户的相似度\n",
      "计算到用户：654与其余用户的相似度\n",
      "计算到用户：655与其余用户的相似度\n",
      "计算到用户：656与其余用户的相似度\n",
      "计算到用户：657与其余用户的相似度\n",
      "计算到用户：658与其余用户的相似度\n",
      "计算到用户：659与其余用户的相似度\n",
      "计算到用户：660与其余用户的相似度\n",
      "计算到用户：661与其余用户的相似度\n",
      "计算到用户：662与其余用户的相似度\n",
      "计算到用户：663与其余用户的相似度\n",
      "计算到用户：664与其余用户的相似度\n",
      "计算到用户：665与其余用户的相似度\n",
      "计算到用户：666与其余用户的相似度\n",
      "计算到用户：667与其余用户的相似度\n",
      "计算到用户：668与其余用户的相似度\n",
      "计算到用户：669与其余用户的相似度\n",
      "计算到用户：670与其余用户的相似度\n",
      "计算到用户：671与其余用户的相似度\n",
      "计算到用户：672与其余用户的相似度\n",
      "计算到用户：673与其余用户的相似度\n",
      "计算到用户：674与其余用户的相似度\n",
      "计算到用户：675与其余用户的相似度\n",
      "计算到用户：676与其余用户的相似度\n",
      "计算到用户：677与其余用户的相似度\n",
      "计算到用户：678与其余用户的相似度\n",
      "计算到用户：679与其余用户的相似度\n",
      "计算到用户：680与其余用户的相似度\n",
      "计算到用户：681与其余用户的相似度\n",
      "计算到用户：682与其余用户的相似度\n",
      "计算到用户：683与其余用户的相似度\n",
      "计算到用户：684与其余用户的相似度\n",
      "计算到用户：685与其余用户的相似度\n",
      "计算到用户：686与其余用户的相似度\n",
      "计算到用户：687与其余用户的相似度\n",
      "计算到用户：688与其余用户的相似度\n",
      "计算到用户：689与其余用户的相似度\n",
      "计算到用户：690与其余用户的相似度\n",
      "计算到用户：691与其余用户的相似度\n",
      "计算到用户：692与其余用户的相似度\n",
      "计算到用户：693与其余用户的相似度\n",
      "计算到用户：694与其余用户的相似度\n",
      "计算到用户：695与其余用户的相似度\n",
      "计算到用户：696与其余用户的相似度\n",
      "计算到用户：697与其余用户的相似度\n",
      "计算到用户：698与其余用户的相似度\n",
      "计算到用户：699与其余用户的相似度\n",
      "计算到用户：700与其余用户的相似度\n",
      "计算到用户：701与其余用户的相似度\n",
      "计算到用户：702与其余用户的相似度\n",
      "计算到用户：703与其余用户的相似度\n",
      "计算到用户：704与其余用户的相似度\n",
      "计算到用户：705与其余用户的相似度\n",
      "计算到用户：706与其余用户的相似度\n",
      "计算到用户：707与其余用户的相似度\n",
      "计算到用户：708与其余用户的相似度\n",
      "计算到用户：709与其余用户的相似度\n",
      "计算到用户：710与其余用户的相似度\n",
      "计算到用户：711与其余用户的相似度\n",
      "计算到用户：712与其余用户的相似度\n",
      "计算到用户：713与其余用户的相似度\n",
      "计算到用户：714与其余用户的相似度\n",
      "计算到用户：715与其余用户的相似度\n",
      "计算到用户：716与其余用户的相似度\n",
      "计算到用户：717与其余用户的相似度\n",
      "计算到用户：718与其余用户的相似度\n",
      "计算到用户：719与其余用户的相似度\n",
      "计算到用户：720与其余用户的相似度\n",
      "计算到用户：721与其余用户的相似度\n",
      "计算到用户：722与其余用户的相似度\n",
      "计算到用户：723与其余用户的相似度\n",
      "计算到用户：724与其余用户的相似度\n",
      "计算到用户：725与其余用户的相似度\n",
      "计算到用户：726与其余用户的相似度\n",
      "计算到用户：727与其余用户的相似度\n",
      "计算到用户：728与其余用户的相似度\n",
      "计算到用户：729与其余用户的相似度\n",
      "计算到用户：730与其余用户的相似度\n",
      "计算到用户：731与其余用户的相似度\n",
      "计算到用户：732与其余用户的相似度\n",
      "计算到用户：733与其余用户的相似度\n",
      "计算到用户：734与其余用户的相似度\n",
      "计算到用户：735与其余用户的相似度\n",
      "计算到用户：736与其余用户的相似度\n",
      "计算到用户：737与其余用户的相似度\n",
      "计算到用户：738与其余用户的相似度\n",
      "计算到用户：739与其余用户的相似度\n",
      "计算到用户：740与其余用户的相似度\n",
      "计算到用户：741与其余用户的相似度\n",
      "计算到用户：742与其余用户的相似度\n",
      "计算到用户：743与其余用户的相似度\n",
      "计算到用户：744与其余用户的相似度\n",
      "计算到用户：745与其余用户的相似度\n",
      "计算到用户：746与其余用户的相似度\n",
      "计算到用户：747与其余用户的相似度\n",
      "计算到用户：748与其余用户的相似度\n",
      "计算到用户：749与其余用户的相似度\n",
      "计算到用户：750与其余用户的相似度\n",
      "计算到用户：751与其余用户的相似度\n",
      "计算到用户：752与其余用户的相似度\n",
      "计算到用户：753与其余用户的相似度\n",
      "计算到用户：754与其余用户的相似度\n",
      "计算到用户：755与其余用户的相似度\n",
      "计算到用户：756与其余用户的相似度\n",
      "计算到用户：757与其余用户的相似度\n",
      "计算到用户：758与其余用户的相似度\n",
      "计算到用户：759与其余用户的相似度\n",
      "计算到用户：760与其余用户的相似度\n",
      "计算到用户：761与其余用户的相似度\n",
      "计算到用户：762与其余用户的相似度\n",
      "计算到用户：763与其余用户的相似度\n",
      "计算到用户：764与其余用户的相似度\n",
      "计算到用户：765与其余用户的相似度\n",
      "计算到用户：766与其余用户的相似度\n",
      "计算到用户：767与其余用户的相似度\n",
      "计算到用户：768与其余用户的相似度\n",
      "计算到用户：769与其余用户的相似度\n",
      "计算到用户：770与其余用户的相似度\n",
      "计算到用户：771与其余用户的相似度\n",
      "计算到用户：772与其余用户的相似度\n",
      "计算到用户：773与其余用户的相似度\n",
      "计算到用户：774与其余用户的相似度\n",
      "计算到用户：775与其余用户的相似度\n",
      "计算到用户：776与其余用户的相似度\n",
      "计算到用户：777与其余用户的相似度\n",
      "计算到用户：778与其余用户的相似度\n",
      "计算到用户：779与其余用户的相似度\n",
      "计算到用户：780与其余用户的相似度\n",
      "计算到用户：781与其余用户的相似度\n",
      "计算到用户：782与其余用户的相似度\n",
      "计算到用户：783与其余用户的相似度\n",
      "计算到用户：784与其余用户的相似度\n",
      "计算到用户：785与其余用户的相似度\n",
      "计算到用户：786与其余用户的相似度\n",
      "计算到用户：787与其余用户的相似度\n",
      "计算到用户：788与其余用户的相似度\n",
      "计算到用户：789与其余用户的相似度\n",
      "计算到用户：790与其余用户的相似度\n",
      "计算到用户：791与其余用户的相似度\n",
      "计算到用户：792与其余用户的相似度\n",
      "计算到用户：793与其余用户的相似度\n",
      "计算到用户：794与其余用户的相似度\n",
      "计算到用户：795与其余用户的相似度\n",
      "计算到用户：796与其余用户的相似度\n",
      "计算到用户：797与其余用户的相似度\n",
      "计算到用户：798与其余用户的相似度\n",
      "计算到用户：799与其余用户的相似度\n",
      "计算到用户：800与其余用户的相似度\n",
      "计算到用户：801与其余用户的相似度\n",
      "计算到用户：802与其余用户的相似度\n",
      "计算到用户：803与其余用户的相似度\n",
      "计算到用户：804与其余用户的相似度\n",
      "计算到用户：805与其余用户的相似度\n",
      "计算到用户：806与其余用户的相似度\n",
      "计算到用户：807与其余用户的相似度\n",
      "计算到用户：808与其余用户的相似度\n",
      "计算到用户：809与其余用户的相似度\n",
      "计算到用户：810与其余用户的相似度\n",
      "计算到用户：811与其余用户的相似度\n",
      "计算到用户：812与其余用户的相似度\n",
      "计算到用户：813与其余用户的相似度\n",
      "计算到用户：814与其余用户的相似度\n",
      "计算到用户：815与其余用户的相似度\n",
      "计算到用户：816与其余用户的相似度\n",
      "计算到用户：817与其余用户的相似度\n",
      "计算到用户：818与其余用户的相似度\n",
      "计算到用户：819与其余用户的相似度\n",
      "计算到用户：820与其余用户的相似度\n",
      "计算到用户：821与其余用户的相似度\n",
      "计算到用户：822与其余用户的相似度\n",
      "计算到用户：823与其余用户的相似度\n",
      "计算到用户：824与其余用户的相似度\n",
      "计算到用户：825与其余用户的相似度\n",
      "计算到用户：826与其余用户的相似度\n",
      "计算到用户：827与其余用户的相似度\n",
      "计算到用户：828与其余用户的相似度\n",
      "计算到用户：829与其余用户的相似度\n",
      "计算到用户：830与其余用户的相似度\n",
      "计算到用户：831与其余用户的相似度\n",
      "计算到用户：832与其余用户的相似度\n",
      "计算到用户：833与其余用户的相似度\n",
      "计算到用户：834与其余用户的相似度\n",
      "计算到用户：835与其余用户的相似度\n",
      "计算到用户：836与其余用户的相似度\n",
      "计算到用户：837与其余用户的相似度\n",
      "计算到用户：838与其余用户的相似度\n",
      "计算到用户：839与其余用户的相似度\n",
      "计算到用户：840与其余用户的相似度\n",
      "计算到用户：841与其余用户的相似度\n",
      "计算到用户：842与其余用户的相似度\n",
      "计算到用户：843与其余用户的相似度\n",
      "计算到用户：844与其余用户的相似度\n",
      "计算到用户：845与其余用户的相似度\n",
      "计算到用户：846与其余用户的相似度\n",
      "计算到用户：847与其余用户的相似度\n",
      "计算到用户：848与其余用户的相似度\n",
      "计算到用户：849与其余用户的相似度\n",
      "计算到用户：850与其余用户的相似度\n",
      "计算到用户：851与其余用户的相似度\n",
      "计算到用户：852与其余用户的相似度\n",
      "计算到用户：853与其余用户的相似度\n",
      "计算到用户：854与其余用户的相似度\n",
      "计算到用户：855与其余用户的相似度\n",
      "计算到用户：856与其余用户的相似度\n",
      "计算到用户：857与其余用户的相似度\n",
      "计算到用户：858与其余用户的相似度\n",
      "计算到用户：859与其余用户的相似度\n",
      "计算到用户：860与其余用户的相似度\n",
      "计算到用户：861与其余用户的相似度\n",
      "计算到用户：862与其余用户的相似度\n",
      "计算到用户：863与其余用户的相似度\n",
      "计算到用户：864与其余用户的相似度\n",
      "计算到用户：865与其余用户的相似度\n",
      "计算到用户：866与其余用户的相似度\n",
      "计算到用户：867与其余用户的相似度\n",
      "计算到用户：868与其余用户的相似度\n",
      "计算到用户：869与其余用户的相似度\n",
      "计算到用户：870与其余用户的相似度\n",
      "计算到用户：871与其余用户的相似度\n",
      "计算到用户：872与其余用户的相似度\n",
      "计算到用户：873与其余用户的相似度\n",
      "计算到用户：874与其余用户的相似度\n",
      "计算到用户：875与其余用户的相似度\n",
      "计算到用户：876与其余用户的相似度\n",
      "计算到用户：877与其余用户的相似度\n",
      "计算到用户：878与其余用户的相似度\n",
      "计算到用户：879与其余用户的相似度\n",
      "计算到用户：880与其余用户的相似度\n",
      "计算到用户：881与其余用户的相似度\n",
      "计算到用户：882与其余用户的相似度\n",
      "计算到用户：883与其余用户的相似度\n",
      "计算到用户：884与其余用户的相似度\n",
      "计算到用户：885与其余用户的相似度\n",
      "计算到用户：886与其余用户的相似度\n",
      "计算到用户：887与其余用户的相似度\n",
      "计算到用户：888与其余用户的相似度\n",
      "计算到用户：889与其余用户的相似度\n",
      "计算到用户：890与其余用户的相似度\n",
      "计算到用户：891与其余用户的相似度\n",
      "计算到用户：892与其余用户的相似度\n",
      "计算到用户：893与其余用户的相似度\n",
      "计算到用户：894与其余用户的相似度\n",
      "计算到用户：895与其余用户的相似度\n",
      "计算到用户：896与其余用户的相似度\n",
      "计算到用户：897与其余用户的相似度\n",
      "计算到用户：898与其余用户的相似度\n",
      "计算到用户：899与其余用户的相似度\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "计算到用户：900与其余用户的相似度\n",
      "计算到用户：901与其余用户的相似度\n",
      "计算到用户：902与其余用户的相似度\n",
      "计算到用户：903与其余用户的相似度\n",
      "计算到用户：904与其余用户的相似度\n",
      "计算到用户：905与其余用户的相似度\n",
      "计算到用户：906与其余用户的相似度\n",
      "计算到用户：907与其余用户的相似度\n",
      "计算到用户：908与其余用户的相似度\n",
      "计算到用户：909与其余用户的相似度\n",
      "计算到用户：910与其余用户的相似度\n",
      "计算到用户：911与其余用户的相似度\n",
      "计算到用户：912与其余用户的相似度\n",
      "计算到用户：913与其余用户的相似度\n",
      "计算到用户：914与其余用户的相似度\n",
      "计算到用户：915与其余用户的相似度\n",
      "计算到用户：916与其余用户的相似度\n",
      "计算到用户：917与其余用户的相似度\n",
      "计算到用户：918与其余用户的相似度\n",
      "计算到用户：919与其余用户的相似度\n",
      "计算到用户：920与其余用户的相似度\n",
      "计算到用户：921与其余用户的相似度\n",
      "计算到用户：922与其余用户的相似度\n",
      "计算到用户：923与其余用户的相似度\n",
      "计算到用户：924与其余用户的相似度\n",
      "计算到用户：925与其余用户的相似度\n",
      "计算到用户：926与其余用户的相似度\n",
      "计算到用户：927与其余用户的相似度\n",
      "计算到用户：928与其余用户的相似度\n",
      "计算到用户：929与其余用户的相似度\n",
      "计算到用户：930与其余用户的相似度\n",
      "计算到用户：931与其余用户的相似度\n",
      "计算到用户：932与其余用户的相似度\n",
      "计算到用户：933与其余用户的相似度\n",
      "计算到用户：934与其余用户的相似度\n",
      "计算到用户：935与其余用户的相似度\n",
      "计算到用户：936与其余用户的相似度\n",
      "计算到用户：937与其余用户的相似度\n",
      "计算到用户：938与其余用户的相似度\n",
      "计算到用户：939与其余用户的相似度\n",
      "计算到用户：940与其余用户的相似度\n",
      "计算到用户：941与其余用户的相似度\n",
      "计算到用户：942与其余用户的相似度\n"
     ]
    }
   ],
   "source": [
    "user_similarity_array = np.zeros(shape=(len(user_id_s),len(user_id_s)))\n",
    "for user_index1 in range(len(user_id_s)):\n",
    "    print('计算到用户：%s与其余用户的相似度' % user_index1)\n",
    "    for user_index2 in range(user_index1 + 1,len(user_id_s)):\n",
    "        # 计算用户1和用户2的相似度\n",
    "        sim = calculate_sim(user_index1,user_index2)\n",
    "        # 用户1与用户2的相似度=sim\n",
    "        user_similarity_array[user_index1,user_index2] = sim\n",
    "        # 用户2与用户1的相似度=sim\n",
    "        user_similarity_array[user_index2,user_index1] = sim"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.  ,  0.52,  0.53, ...,  0.81, -0.18,  0.3 ],\n",
       "       [ 0.52,  0.  ,  0.14, ...,  0.04,  0.25,  0.71],\n",
       "       [ 0.53,  0.14,  0.  , ...,  0.74,  0.51,  1.  ],\n",
       "       ...,\n",
       "       [ 0.81,  0.04,  0.74, ...,  0.  , -0.46,  0.01],\n",
       "       [-0.18,  0.25,  0.51, ..., -0.46,  0.  ,  0.42],\n",
       "       [ 0.3 ,  0.71,  1.  , ...,  0.01,  0.42,  0.  ]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 打印用户相似度矩阵\n",
    "user_similarity_array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "预测到用户0\n",
      "预测到用户1\n",
      "预测到用户2\n",
      "预测到用户3\n",
      "预测到用户4\n",
      "预测到用户5\n",
      "预测到用户6\n",
      "预测到用户7\n",
      "预测到用户8\n",
      "预测到用户9\n",
      "预测到用户10\n",
      "预测到用户11\n",
      "预测到用户12\n",
      "预测到用户13\n",
      "预测到用户14\n",
      "预测到用户15\n",
      "预测到用户16\n",
      "预测到用户17\n",
      "预测到用户18\n",
      "预测到用户19\n",
      "预测到用户20\n",
      "预测到用户21\n",
      "预测到用户22\n",
      "预测到用户23\n",
      "预测到用户24\n",
      "预测到用户25\n",
      "预测到用户26\n",
      "预测到用户27\n",
      "预测到用户28\n",
      "预测到用户29\n",
      "预测到用户30\n",
      "预测到用户31\n",
      "预测到用户32\n",
      "预测到用户33\n",
      "预测到用户34\n",
      "预测到用户35\n",
      "预测到用户36\n",
      "预测到用户37\n",
      "预测到用户38\n",
      "预测到用户39\n",
      "预测到用户40\n",
      "预测到用户41\n",
      "预测到用户42\n",
      "预测到用户43\n",
      "预测到用户44\n",
      "预测到用户45\n",
      "预测到用户46\n",
      "预测到用户47\n",
      "预测到用户48\n",
      "预测到用户49\n",
      "预测到用户50\n",
      "预测到用户51\n",
      "预测到用户52\n",
      "预测到用户53\n",
      "预测到用户54\n",
      "预测到用户55\n",
      "预测到用户56\n",
      "预测到用户57\n",
      "预测到用户58\n",
      "预测到用户59\n",
      "预测到用户60\n",
      "预测到用户61\n",
      "预测到用户62\n",
      "预测到用户63\n",
      "预测到用户64\n",
      "预测到用户65\n",
      "预测到用户66\n",
      "预测到用户67\n",
      "预测到用户68\n",
      "预测到用户69\n",
      "预测到用户70\n",
      "预测到用户71\n",
      "预测到用户72\n",
      "预测到用户73\n",
      "预测到用户74\n",
      "预测到用户75\n",
      "预测到用户76\n",
      "预测到用户77\n",
      "预测到用户78\n",
      "预测到用户79\n",
      "预测到用户80\n",
      "预测到用户81\n",
      "预测到用户82\n",
      "预测到用户83\n",
      "预测到用户84\n",
      "预测到用户85\n",
      "预测到用户86\n",
      "预测到用户87\n",
      "预测到用户88\n",
      "预测到用户89\n",
      "预测到用户90\n",
      "预测到用户91\n",
      "预测到用户92\n",
      "预测到用户93\n",
      "预测到用户94\n",
      "预测到用户95\n",
      "预测到用户96\n",
      "预测到用户97\n",
      "预测到用户98\n",
      "预测到用户99\n",
      "预测到用户100\n",
      "预测到用户101\n",
      "预测到用户102\n",
      "预测到用户103\n",
      "预测到用户104\n",
      "预测到用户105\n",
      "预测到用户106\n",
      "预测到用户107\n",
      "预测到用户108\n",
      "预测到用户109\n",
      "预测到用户110\n",
      "预测到用户111\n",
      "预测到用户112\n",
      "预测到用户113\n",
      "预测到用户114\n",
      "预测到用户115\n",
      "预测到用户116\n",
      "预测到用户117\n",
      "预测到用户118\n",
      "预测到用户119\n",
      "预测到用户120\n",
      "预测到用户121\n",
      "预测到用户122\n",
      "预测到用户123\n",
      "预测到用户124\n",
      "预测到用户125\n",
      "预测到用户126\n",
      "预测到用户127\n",
      "预测到用户128\n",
      "预测到用户129\n",
      "预测到用户130\n",
      "预测到用户131\n",
      "预测到用户132\n",
      "预测到用户133\n",
      "预测到用户134\n",
      "预测到用户135\n",
      "预测到用户136\n",
      "预测到用户137\n",
      "预测到用户138\n",
      "预测到用户139\n",
      "预测到用户140\n",
      "预测到用户141\n",
      "预测到用户142\n",
      "预测到用户143\n",
      "预测到用户144\n",
      "预测到用户145\n",
      "预测到用户146\n",
      "预测到用户147\n",
      "预测到用户148\n",
      "预测到用户149\n",
      "预测到用户150\n",
      "预测到用户151\n",
      "预测到用户152\n",
      "预测到用户153\n",
      "预测到用户154\n",
      "预测到用户155\n",
      "预测到用户156\n",
      "预测到用户157\n",
      "预测到用户158\n",
      "预测到用户159\n",
      "预测到用户160\n",
      "预测到用户161\n",
      "预测到用户162\n",
      "预测到用户163\n",
      "预测到用户164\n",
      "预测到用户165\n",
      "预测到用户166\n",
      "预测到用户167\n",
      "预测到用户168\n",
      "预测到用户169\n",
      "预测到用户170\n",
      "预测到用户171\n",
      "预测到用户172\n",
      "预测到用户173\n",
      "预测到用户174\n",
      "预测到用户175\n",
      "预测到用户176\n",
      "预测到用户177\n",
      "预测到用户178\n",
      "预测到用户179\n",
      "预测到用户180\n",
      "预测到用户181\n",
      "预测到用户182\n",
      "预测到用户183\n",
      "预测到用户184\n",
      "预测到用户185\n",
      "预测到用户186\n",
      "预测到用户187\n",
      "预测到用户188\n",
      "预测到用户189\n",
      "预测到用户190\n",
      "预测到用户191\n",
      "预测到用户192\n",
      "预测到用户193\n",
      "预测到用户194\n",
      "预测到用户195\n",
      "预测到用户196\n",
      "预测到用户197\n",
      "预测到用户198\n",
      "预测到用户199\n",
      "预测到用户200\n",
      "预测到用户201\n",
      "预测到用户202\n",
      "预测到用户203\n",
      "预测到用户204\n",
      "预测到用户205\n",
      "预测到用户206\n",
      "预测到用户207\n",
      "预测到用户208\n",
      "预测到用户209\n",
      "预测到用户210\n",
      "预测到用户211\n",
      "预测到用户212\n",
      "预测到用户213\n",
      "预测到用户214\n",
      "预测到用户215\n",
      "预测到用户216\n",
      "预测到用户217\n",
      "预测到用户218\n",
      "预测到用户219\n",
      "预测到用户220\n",
      "预测到用户221\n",
      "预测到用户222\n",
      "预测到用户223\n",
      "预测到用户224\n",
      "预测到用户225\n",
      "预测到用户226\n",
      "预测到用户227\n",
      "预测到用户228\n",
      "预测到用户229\n",
      "预测到用户230\n",
      "预测到用户231\n",
      "预测到用户232\n",
      "预测到用户233\n",
      "预测到用户234\n",
      "预测到用户235\n",
      "预测到用户236\n",
      "预测到用户237\n",
      "预测到用户238\n",
      "预测到用户239\n",
      "预测到用户240\n",
      "预测到用户241\n",
      "预测到用户242\n",
      "预测到用户243\n",
      "预测到用户244\n",
      "预测到用户245\n",
      "预测到用户246\n",
      "预测到用户247\n",
      "预测到用户248\n",
      "预测到用户249\n",
      "预测到用户250\n",
      "预测到用户251\n",
      "预测到用户252\n",
      "预测到用户253\n",
      "预测到用户254\n",
      "预测到用户255\n",
      "预测到用户256\n",
      "预测到用户257\n",
      "预测到用户258\n",
      "预测到用户259\n",
      "预测到用户260\n",
      "预测到用户261\n",
      "预测到用户262\n",
      "预测到用户263\n",
      "预测到用户264\n",
      "预测到用户265\n",
      "预测到用户266\n",
      "预测到用户267\n",
      "预测到用户268"
     ]
    }
   ],
   "source": [
    "# 用户对商品的预测矩阵，已打分的商品，预测分数为0分\n",
    "user_item_predict_rating_array = np.zeros_like(user_item_rating_array)\n",
    "\n",
    "# 对所有的用户index进行遍历\n",
    "for user_index in range(len(user_id_s)):\n",
    "    print('预测到用户%s' % user_index)\n",
    "    # 对所有商品进行遍历\n",
    "    for item_index in range(len(item_id_s)):\n",
    "        # 如果这个商品没有被打过分\n",
    "        if item_index not in user_rating_map[user_index]:\n",
    "            # 找到对这个商品打过分的所有用户的索引\n",
    "            user_rating_index_v = np.where(\n",
    "                user_item_rating_array[:,item_index] > 0\n",
    "            )[0]\n",
    "            # 如果没有用户对这个商品打过分，continue\n",
    "            if not list(user_rating_index_v):\n",
    "                continue\n",
    "            # 根据用户打分的索引，从用户相似度矩阵中取出相似度向量\n",
    "            user_sim_v = np.take(\n",
    "                user_similarity_array[user_index],\n",
    "                user_rating_index_v,\n",
    "            )\n",
    "            # 计算相似度绝对值加和\n",
    "            user_sim_abs_sum = user_sim_v.__abs__().sum()\n",
    "            # 如果相似度绝对值加和为0（也就是存在对这个商品打过分的用户群体，但这些用户群体与目标用户的相关度都为0），continue\n",
    "            if user_sim_abs_sum == 0:\n",
    "                continue\n",
    "            # 得到用户打分的向量，并去掉平均值\n",
    "            user_rating_v = np.take(\n",
    "                user_item_rating_array[:,item_index],\n",
    "                user_rating_index_v\n",
    "            ) - np.take(\n",
    "                user_rating_mu_s,\n",
    "                user_rating_index_v\n",
    "            )\n",
    "            # 根据公式，得到预测的结果，这里保留两位小数\n",
    "#             predict_rating = round(\n",
    "#                 (np.dot(user_rating_v,user_sim_v) + user_rating_mu_s[user_index])/user_sim_abs_sum\n",
    "#                 ,2\n",
    "#             ) + user_rating_mu_s[user_index]\n",
    "            predict_rating = round(\n",
    "                np.dot(user_rating_v,user_sim_v)/user_sim_abs_sum\n",
    "                ,2\n",
    "            ) + user_rating_mu_s[user_index]\n",
    "            # 把预测的结果添加到预测矩阵中\n",
    "            user_item_predict_rating_array[user_index,item_index] = predict_rating\n",
    "# 打印预测矩阵\n",
    "user_item_predict_rating_array    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取测试集\n",
    "df_test_data = pd.read_csv('./data/movielen_rating_test.base',sep='\\t',names=['user_id','item_id','rating'],usecols=[0,1,2])\n",
    "df_test_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 测试集中不重复的用户id\n",
    "user_test_unique_s = df_test_data['user_id'].unique()\n",
    "# 创建一个列表，保存测试集中的user_id对应的user_index\n",
    "user_index_test_s = []\n",
    "# 对测试集中的用户id进行遍历\n",
    "for user_id in user_test_unique_s:\n",
    "    # 如果测试集中的用户id在训练集的用户索引map中，添加这个user_index\n",
    "    if user_id in user_index_map.keys():\n",
    "        user_index_test_s.append(user_index_map[user_id])\n",
    "# 打印测试集中的user_index列表\n",
    "user_index_test_s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建一个用户对商品打分的dataframe\n",
    "df_user_item_rating_test = pd.DataFrame(np.zeros(shape=(len(user_index_test_s),len(item_id_s))))\n",
    "# dataframe的index设置为在训练集中存在的测试集的user_index\n",
    "df_user_item_rating_test.index = user_index_test_s\n",
    "# 对dataframe的index进行遍历\n",
    "for row_index in df_test_data.index:\n",
    "    print('运行到%s行'% row_index)\n",
    "    row_data = df_test_data.loc[row_index]\n",
    "    # 如果这个用户id在user_rating_map中，商品id也在item_index_map中，添加这次打分\n",
    "    if row_data['user_id'] in user_rating_map.keys() and row_data['item_id'] in item_index_map.keys():\n",
    "        df_user_item_rating_test[item_index_map[row_data['item_id']]][user_index_map[row_data['user_id']]] = row_data['rating']\n",
    "# 打印dataframe\n",
    "df_user_item_rating_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算均方误差\n",
    "def calculate_RMSE():\n",
    "    # acc_locc为分子，二次损失\n",
    "    acc_loss = 0\n",
    "    # acc_num为分母，一共计算了多少项\n",
    "    acc_num = 0\n",
    "    # 对测试集的index进行遍历\n",
    "    for user_index in df_user_item_rating_test.index:\n",
    "        # 测试集中user_index对应的行向量\n",
    "        test_row_data = np.array(df_user_item_rating_test.loc[user_index])\n",
    "        # 预测矩阵中的行向量\n",
    "        predict_row_data = user_item_predict_rating_array[user_index]\n",
    "        # 测试集中对应user_index，打过分的商品索引\n",
    "        test_index_v =  np.where(test_row_data > 0)\n",
    "        # 预测矩阵中对应user_index，打过分的商品索引\n",
    "        predict_index_v = np.where(predict_row_data > 0)\n",
    "        # 取test_index_v和predict_index_v的交集，即预测过打分，而且也在测试集中出现实际打分\n",
    "        intersection_index_s = list(\n",
    "            set(test_index_v[0]) & set(predict_index_v[0])\n",
    "        )\n",
    "        # 如果交集为空，continue\n",
    "        if not intersection_index_s:\n",
    "            continue\n",
    "        # 根据上述的交集索引，取得测试集中的打分向量和预测矩阵中的打分向量\n",
    "        test_rating_v = np.take(test_row_data,intersection_index_s)\n",
    "        predict_rating_v = np.clip(\n",
    "            np.take(predict_row_data,intersection_index_s),0,5\n",
    "        )\n",
    "        # 计算二次损失\n",
    "        acc_loss += np.square(test_rating_v - predict_rating_v).sum()\n",
    "        # 分母叠加个数\n",
    "        acc_num += len(intersection_index_s)\n",
    "    # 得出均方误差\n",
    "    return np.sqrt(acc_loss/acc_num)\n",
    "# 计算均方误差并打印\n",
    "RMSE = calculate_RMSE()\n",
    "RMSE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 推荐商品，predict_quantity是推荐的商品的个数\n",
    "def predict(predict_quantity):\n",
    "    # 建立一个商品推荐字典,保存对user_index推荐的商品索引\n",
    "    # 例如：predict_item_index_map[user_index] = [4,3,2,5] \n",
    "    predict_item_index_map = {}\n",
    "    # 对训练集中所有的user_index进行遍历\n",
    "    for user_index in range(len(user_id_s)):\n",
    "        # 预测矩阵中对应user_index的向量，进行倒序排列\n",
    "        predict_item_index_v = list(np.argsort(-user_item_predict_rating_array[user_index]))\n",
    "        # 取min(min(predict_quantity,len(predict_item_index_v)))个最前面的商品索引，即打分最高的商品索引\n",
    "        predict_item_index_v = predict_item_index_v[0:min(predict_quantity,len(predict_item_index_v))]\n",
    "        # 添加到商品推荐字典中\n",
    "        predict_item_index_map[user_index] = predict_item_index_v\n",
    "    # 返回商品推荐字典\n",
    "    return predict_item_index_map\n",
    "# 推荐50个商品\n",
    "predict_item_index_map = predict(50)\n",
    "# 打印商品推荐字典\n",
    "predict_item_index_map"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算准确率与召回率\n",
    "def calculate_precision_and_recall():\n",
    "    # 推荐的商品也在测试集中出现的总数\n",
    "    union_num = 0\n",
    "    # 推荐的商品的总数\n",
    "    predict_num = 0\n",
    "    # 测试集中出现的商品总数\n",
    "    test_num = 0\n",
    "    # 对测试集的user_index进行遍历\n",
    "    for user_index in df_user_item_rating_test.index:\n",
    "        # 对测试集中的user_index打过分的商品，进行倒排序，得到索引\n",
    "        #（这里其实没有使用到倒序排列功能，比如可以取测试集中倒序的前100个所以test_item_v）\n",
    "        test_item_v = np.where(df_user_item_rating_test[user_index]>=3)[0].tolist()\n",
    "        # 推荐的商品也在测试集中出现的总数做叠加\n",
    "        union_num += len(\n",
    "            set(predict_item_index_map[user_index]) & set(test_item_v)\n",
    "        )\n",
    "        # 推荐的商品的总数做叠加\n",
    "        predict_num += len(predict_item_index_map[user_index])\n",
    "        # 测试集中出现的商品总数做叠加\n",
    "        test_num += len(test_item_v)\n",
    "    # 返回准确率与召回率\n",
    "    return union_num / predict_num,union_num/test_num\n",
    "# 计算准确率与召回率\n",
    "precision,recall = calculate_precision_and_recall()\n",
    "print('precision=',precision)\n",
    "print('recall=',recall)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义计算覆盖率\n",
    "def calculate_coverage():\n",
    "    # 推荐的物品索引集合\n",
    "    predict_item_index_set = set()\n",
    "    # 把所有用户推荐过的商品id都添加到predict_item_index_set里，然后根据predict_item_index_set的数量，计算覆盖度\n",
    "    for user_index in predict_item_index_map.keys():\n",
    "        for item_index in predict_item_index_map[user_index]:\n",
    "            predict_item_index_set.add(item_index)\n",
    "    return len(predict_item_index_set) / len(item_id_s)\n",
    "# 计算并打印覆盖度\n",
    "coverage = calculate_coverage()\n",
    "print('coverage=',coverage)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
